import os
import json
from datetime import datetime


class SongLibraryManager:
    """歌曲库管理器类，负责管理歌曲库文件夹和扫描歌曲文件"""
    
    def __init__(self, settings_file='settings.json'):
        """初始化歌曲库管理器"""
        self.settings_file = settings_file
        self.library_folders = []  # 存储歌曲库文件夹路径
        self.selected_folders = set()  # 存储当前选中的文件夹路径
        self.song_cache = {}  # 缓存扫描到的歌曲，key为文件夹路径，value为歌曲列表
        self.supported_audio_formats = ['.mp3', '.wav', '.flac', '.aac', '.ogg', '.wma', '.m4a']
        
        # 加载配置
        self.load_settings()
    
    def load_settings(self):
        """从设置文件加载歌曲库配置"""
        try:
            if os.path.exists(self.settings_file):
                with open(self.settings_file, 'r', encoding='utf-8') as f:
                    settings = json.load(f)
                    if 'library_folders' in settings:
                        self.library_folders = settings['library_folders']
                    if 'selected_folders' in settings:
                        self.selected_folders = set(settings['selected_folders'])
        except Exception as e:
            print(f"加载歌曲库配置失败: {e}")
    
    def save_settings(self):
        """保存歌曲库配置到设置文件"""
        try:
            with open(self.settings_file, 'r', encoding='utf-8') as f:
                settings = json.load(f)
        except:
            settings = {}
        
        settings['library_folders'] = self.library_folders
        settings['selected_folders'] = list(self.selected_folders)
        
        try:
            with open(self.settings_file, 'w', encoding='utf-8') as f:
                json.dump(settings, f, ensure_ascii=False, indent=4)
            return True
        except Exception as e:
            print(f"保存歌曲库配置失败: {e}")
            return False
    
    def add_library_folder(self, folder_path):
        """添加歌曲库文件夹"""
        if folder_path and os.path.isdir(folder_path) and folder_path not in self.library_folders:
            self.library_folders.append(folder_path)
            self.selected_folders.add(folder_path)  # 添加后默认选中
            return self.save_settings()
        return False
    
    def remove_library_folder(self, folder_path):
        """删除歌曲库文件夹"""
        if folder_path in self.library_folders:
            self.library_folders.remove(folder_path)
            if folder_path in self.selected_folders:
                self.selected_folders.remove(folder_path)
            if folder_path in self.song_cache:
                del self.song_cache[folder_path]
            return self.save_settings()
        return False
    
    def update_folder_path(self, old_path, new_path):
        """更新歌曲库文件夹路径"""
        if old_path in self.library_folders and os.path.isdir(new_path) and new_path != old_path:
            index = self.library_folders.index(old_path)
            self.library_folders[index] = new_path
            
            if old_path in self.selected_folders:
                self.selected_folders.remove(old_path)
                self.selected_folders.add(new_path)
                
            if old_path in self.song_cache:
                del self.song_cache[old_path]
                
            return self.save_settings()
        return False
    
    def toggle_folder_selection(self, folder_path, is_selected):
        """切换文件夹的选中状态"""
        if folder_path in self.library_folders:
            if is_selected:
                self.selected_folders.add(folder_path)
            else:
                # 使用remove方法确保文件夹被正确移除（因为已经确认folder_path在library_folders中）
                if folder_path in self.selected_folders:
                    self.selected_folders.remove(folder_path)
            return self.save_settings()
        return False
    
    def scan_folder_for_songs(self, folder_path):
        """扫描文件夹中的歌曲文件"""
        if folder_path not in self.song_cache:
            songs = []
            try:
                for root, _, files in os.walk(folder_path):
                    for file in files:
                        file_ext = os.path.splitext(file)[1].lower()
                        if file_ext in self.supported_audio_formats:
                            file_path = os.path.join(root, file)
                            songs.append({
                                'filename': file,
                                'path': file_path,
                                'folder': folder_path
                            })
                self.song_cache[folder_path] = songs
            except Exception as e:
                print(f"扫描文件夹失败: {e}")
                self.song_cache[folder_path] = []
        
        return self.song_cache[folder_path]
    
    def get_all_songs(self):
        """获取所有选中文件夹中的歌曲"""
        all_songs = []
        for folder_path in self.selected_folders:
            songs = self.scan_folder_for_songs(folder_path)
            all_songs.extend(songs)
        return all_songs
    
    def refresh_song_cache(self):
        """刷新所有文件夹的歌曲缓存"""
        for folder_path in self.library_folders:
            self.song_cache.pop(folder_path, None)
    
    def get_song_details(self, song_path):
        """获取歌曲的详细信息"""
        if os.path.exists(song_path):
            stats = os.stat(song_path)
            file_size = stats.st_size
            modified_time = datetime.fromtimestamp(stats.st_mtime)
            
            # 文件扩展名
            _, file_ext = os.path.splitext(song_path)
            file_ext = file_ext[1:].upper()  # 去除点并转为大写
            
            # 文件名和路径
            filename = os.path.basename(song_path)
            folder_path = os.path.dirname(song_path)
            
            return {
                'filename': filename,
                'path': song_path,
                'folder_path': folder_path,
                'size': self._format_file_size(file_size),
                'size_bytes': file_size,
                'format': file_ext,
                'modified_time': modified_time.strftime('%Y-%m-%d %H:%M:%S')
            }
        return None
    
    def _format_file_size(self, size_bytes):
        """格式化文件大小"""
        if size_bytes < 1024:
            return f"{size_bytes} B"
        elif size_bytes < 1024 * 1024:
            return f"{size_bytes / 1024:.2f} KB"
        elif size_bytes < 1024 * 1024 * 1024:
            return f"{size_bytes / (1024 * 1024):.2f} MB"
        else:
            return f"{size_bytes / (1024 * 1024 * 1024):.2f} GB"